package net.jarang.sourcegen;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;



import net.jarang.support.FreemakerTemplateUtil;
import net.jarang.support.PropertiesUtil;
import net.jarang.support.db.Column;
import net.jarang.support.db.DBUtil;
import net.jarang.support.db.FieldMapper;
import net.jarang.support.db.PrimaryKey;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import freemarker.template.Template;

public class Generator {
	private static final Log log = LogFactory.getLog(Generator.class);
	protected String resourceName;
	protected String type;
	protected TemplateInfo templateInfo;
	
	public Generator(String resourceName, String type) {
		this.resourceName = resourceName;
		this.type = type;
	}

	protected Writer getWriter(TemplateInfo templateInfo) throws IOException {
		File file = new File(templateInfo.getFilePath());
		file.getParentFile().mkdirs();
		return new FileWriter(file);
	}	

	public void generate() {
		createTemplateInfo();
		setFieldMappers();
		setPrimaryKeyMapers();
		createTemplateFile();
	}

	public void createTemplateInfo() {
		TemplateInfo templateInfo = new TemplateInfo();
		templateInfo.setDomain(PropertiesUtil.getProperties(resourceName).getProperty("domain"));
		templateInfo.setTableName(PropertiesUtil.getProperties(resourceName).getProperty("table.name"));
		templateInfo.setPackageName(PropertiesUtil.getProperties(resourceName).getProperty("package.name"));
		templateInfo.setPrefix(PropertiesUtil.getProperties(resourceName).getProperty(type+".prefix"));
		templateInfo.setSurffix(PropertiesUtil.getProperties(resourceName).getProperty(type+".surffix"));
		templateInfo.setFileExtention(PropertiesUtil.getProperties(resourceName).getProperty(type+".file.extention"));
		templateInfo.setExtendsStr(PropertiesUtil.getProperties(resourceName).getProperty(type+".extends"));
		
		generateImport(templateInfo, PropertiesUtil.getProperties(resourceName).getProperty(type+".import.list"));
		generateImplements(templateInfo, PropertiesUtil.getProperties(resourceName).getProperty(type+".implements.list"));
		generateIsTestCase(templateInfo, PropertiesUtil.getProperties(resourceName).getProperty(type+".test.case"));
		
		this.templateInfo = templateInfo;
	}

	private void generateIsTestCase(TemplateInfo templateInfo, String property) {
		// TODO Auto-generated method stub
		
	}

	private void generateImplements(TemplateInfo templateInfo, String str) {
		String[] strs = StringUtils.split(str, ",");
		
		if (strs == null) {
			return;
		}
		
		for (String each : strs) {
			templateInfo.addImplementsList(each);
		}
	}

	private void generateImport(TemplateInfo templateInfo, String str) {
		String[] strs = StringUtils.split(str, ",");
		
		if (strs == null) {
			return;
		}
		
		for (String each : strs) {
			templateInfo.addImportList(each);
		}
	}

	private void setFieldMappers() {
		if (templateInfo == null) return;
		
		List<Column> columns = DBUtil.getColumns(null, null, templateInfo.getTableName(), null);
		if (columns == null || columns.size() == 0) return;
		
		List<FieldMapper> fieldMappers = new ArrayList<FieldMapper>();
		for (Column column : columns) {
			FieldMapper fieldMapper = new FieldMapper(column);
			fieldMappers.add(fieldMapper);
			if(fieldMapper.isDateType()) {
				templateInfo.setExistDateType(true);
			}
		}
		templateInfo.setFieldMappers(fieldMappers);
	}
	
	private void setPrimaryKeyMapers() {
		List<PrimaryKey> primaryKeys = DBUtil.getPrimaryKeys(null, null, templateInfo.getTableName());
		List<FieldMapper> primaryKeyMappers = new ArrayList<FieldMapper>();
		if (primaryKeys != null && primaryKeys.size() > 0) {
			for (PrimaryKey primaryKey : primaryKeys) {
				FieldMapper primaryKeyMapper = new FieldMapper(getPrimaryKeyColumn(primaryKey));
				primaryKeyMappers.add(primaryKeyMapper);
			}
		}
		templateInfo.setPrimaryKeyMappers(primaryKeyMappers);
	}
	
	private Column getPrimaryKeyColumn(PrimaryKey primaryKey) {
		List<Column> columns = DBUtil.getColumns(null, null, templateInfo.getTableName(), null);
		for (Column column : columns) {
			if(primaryKey.getColumnName().equals(column.getColumnName())) {
				column.setKeySeq(primaryKey.getKeySeq());
				column.setPkName(primaryKey.getPkName());
			}
			return column;
		}
		return new Column(primaryKey.getKeySeq(), primaryKey.getPkName());
	}

	private void createTemplateFile() {
		Template textTemplate;
		try {
			textTemplate = FreemakerTemplateUtil.createTemplate(type);
			textTemplate.process(templateInfo, getWriter(templateInfo));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}	

	public String getResourceName() {
		return resourceName;
	}

	public void setResourceName(String resourceName) {
		this.resourceName = resourceName;
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}
}
